package cn.com.utils;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

/**
 * Redisson延时迟队列实用程序
 *
 * @author LiuGuodong
 * @date 2024/09/09
 */
@Slf4j
public class RedissonDelayQueueUtil {

    private final RedissonClient redissonClient;

    public RedissonDelayQueueUtil(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    /**
     * 添加任务到延时队列
     *
     * @param queueName 队列名称
     * @param task      任务内容
     * @param delay     延时时间
     * @param timeUnit  时间单位
     */
    public void addTaskToDelayQueue(String queueName, String task, long delay, TimeUnit timeUnit) {
        RBlockingDeque<String> blockingDeque = redissonClient.getBlockingDeque(queueName);
        RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);

        try {
            log.info("{} 添加任务 {} 到延时队列: {}, 延时 {} {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                    task, queueName, delay, timeUnit.name());
            delayedQueue.offer(task, delay, timeUnit);
        } finally {
            delayedQueue.destroy();  // 确保资源得到正确释放
        }
    }

    /**
     * 从延时队列中获取任务
     *
     * @param queueName 队列名称
     * @return 任务内容
     * @throws InterruptedException 如果线程被中断
     */
    public String getTaskFromDelayQueue(String queueName) throws InterruptedException {
        RBlockingDeque<String> blockingDeque = redissonClient.getBlockingDeque(queueName);
        log.info("{} 正在获取任务从延时队列: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), queueName);
        return blockingDeque.take();
    }

}
